harbor ci-cd
CI流水线中制品库集成
镜像规范
业务/服务:commitId
镜像上传
docker login 192.168.1.200:8088
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
docker tag nginx:1.9.1 192.168.1.200:8088/devops03/devops03-maven-service:1.9.1
docker push 192.168.1.200:8088/devops03/devops03-maven-service:1.9.1
镜像下载
docker pull 192.168.1.200:8088/devops03/devops03-maven-service:1.9.1
CI流水线集成
💘 实践:harbor CI流水线中制品库集成(测试成功)-2022.6.25 |
1.Jenkins
pipeline {
agent {
label "build"
}
stages {
stage("DockerBuild"){
steps{
script{
imageName = "${env.buName}/${env.serviceName}"
imageTag = "${env.branchName}-${env.commitID}"
sh """
#登录镜像仓库
docker login -u admin -p Harbor12345 192.168.1.200:8088
# 构建镜像
docker build -t 192.168.1.200:8088/${imageName}:${imageTag} .
# 上传镜像
docker push 192.168.1.200:8088/${imageName}:${imageTag}
# 删除镜像
sleep 2
docker rmi 192.168.1.200:8088/${imageName}:${imageTag}
"""
}
}
}
}
}
}
- 我们先手动上传下镜像到harbor里:
自己的构建机器要配置下这个:
- 来到
devops4-maven-service
项目,创建一个dockerfile:
- 先给它加进去看下效果:
来到devops4-maven-service
,给它创建一个Dockerfile文件:
再将本次代码拷贝到共享库里,看下效果:
- 构建并观察效果
符合预期。😘
2.GitLabCI
.dockerbuild:
tags:
- "${RUNNER_TAG}"
stage: dockerbuild
rules:
- if: '$RUN_TYPE == "CI"'
when: always
- when: never
script:
|-
imageName=${CI_PROJECT_ROOT_NAMESPACE}/${CI_PROJECT_NAME}:${CI_COMMIT_BRANCH}-${CI_COMMIT_SHORT_SHA}
#登录镜像仓库
docker login -u admin -p Harbor12345 192.168.1.200:8088
# 构建镜像
docker build -t 192.168.1.200:8088/${imageName} .
# 上传镜像
docker push 192.168.1.200:8088/${imageName}
# 删除镜像
sleep 2
docker rmi 192.168.1.200:8088/${imageName}
📍 自己测试过程:
- 配置代码:
我这里为啥报了这个错误呢?
串行和并行都测试过了的啊:
估计是自己的gitlab-runner用户权限不对,这里在上面配置上sudo:
再次尝试就可以了。。
记得上次老师没做过这个配置啊……
- 并行测试:
奇怪啊,老师,当时记得是并行测试时有问题的……
- 串行测试:
注意:因为前面jenkins那里已经上传了一个相同镜像,所以这里只显示为一个;
符合预期。😘
🍀 问题
- 问题现象
之前老版本harbor测试,都没报这个错误来着的;
新版本测试,为啥报这个错误了呢?
jenkins上都可以正常推送上去,但是gitlab-CI就有问题了;
We trust you have received the usual lecture from the local System
18Administrator. It usually boils down to these three things:
19 #1) Respect the privacy of others.
20 #2) Think before you type.
21 #3) With great power comes great responsibility.
22sudo: no tty present and no askpass program specified
- 这里测试都是可以使用sudo命令的啊……
- 最后发现,串行测试没问题,但是并行测试一直报这个错误……奇怪
Harbor REST API
http://192.168.1.200:8088/devcenter-api-2.0
Harbor API 实践【New】
💘 实践:Harbor API 实践(批量删除docker镜像)-2022.6.25 |
在Harbor中批量的创建一些标签
创建一个Jenkins作业, 不需要配置任何参数。 只需要把Jenkinfile内容放进去。
jenkinsfile内容:
- 通过API 获取所有的tag标签列表。
- 将标签信息用INPUT交互式的展示。
- 调用删除接口,删除镜像标签。
import groovy.json.JsonSlurper
/*
清理docker镜像
1. 获取镜像列表
2. 用户选择删除
3. 调用api删除
*/
pipeline {
agent {
label "build"
}
stages{
stage("GetTags"){
steps{
script{
env.projectName = "acmp"
env.repoName = "acmp-nginx-service"
env.result = GetArtifactTag(env.projectName, env.repoName)
env.result = env.result - '[' - ']'
}
}
}
stage("Clean"){
steps{
script{
def result = input message: "是否删除${env.projectName}项目的${env.repoName}这些标签:",
parameters: [extendedChoice(defaultValue: "${env.result}",
multiSelectDelimiter: ',',
name: 'taga',
quoteValue: false,
saveJSONParameterToFile: false,
type: 'PT_CHECKBOX',
value: "${env.result}",
visibleItemCount: 20)]
println("${result}")
// println("Delete ${taga}, doing.......")
// tags = "${taga}" - '[' - ']'
for(t in result.split(',')){
println("Delete >>>>" + t.trim())
DeleteArtifactTag(env.projectName,env.repoName, t.trim())
}
}
}
}
}
}
// 删除镜像tag
def DeleteArtifactTag(projectName,repoName, tagName){
harborAPI = "http://192.168.1.200:8088/api/v2.0/projects/${projectName}/repositories/${repoName}"
apiURL = "artifacts/${tagName}/tags/${tagName}"
sh """ curl -X DELETE "${harborAPI}/${apiURL}" -H "accept: application/json" -u admin:Harbor12345 """
}
// 获取镜像的所有标签
// acmp-nginx-service
def GetArtifactTag(projectName,repoName ){
harborAPI = "http://192.168.1.200:8088/api/v2.0/projects/${projectName}/repositories/${repoName}"
apiURL = "artifacts?page=1&page_size=10"
response = sh returnStdout: true, script: """curl -X GET "${harborAPI}/${apiURL}" -H "accept: application/json" -u admin:Harbor12345 """
response = readJSON text: """${response - "\n"}"""
tags = []
for (t in response[0].tags){
tags << t.name
}
return tags
}
最终效果:【Harbor镜像已经清空了】
📍 自己测试过程:
- 来到
devops4-maven-service
仓库,创建一个新分支:
然后在jenkins里跑一次流水线:
相同的镜像,harbor就自动给你归类了:
- 这里在做一个小小的改动:
- 创建一个jeninks job:
devops4-clean-harbor
- 安装插件
- 开始构建:
点击这个Input requested:
老师这里当时好像也是只选择了一个镜像,次问题暂且搁置吧……🤣
这里只是把tag给去掉了:
但是,再跑一次的话就会报错……
实验结束。
本次完整代码如下:
import groovy.json.JsonSlurper
/*
清理docker镜像
1. 获取镜像列表
2. 用户选择删除
3. 调用api删除
*/
pipeline {
agent {
label "build"
}
stages{
stage("GetTags"){
steps{
script{
env.projectName = "${env.repoName}".split("-")[0]
env.result = GetArtifactTag(env.projectName, env.repoName)
env.result = env.result - '[' - ']'
}
}
}
stage("Clean"){
steps{
script{
def result = input message: "是否删除${env.projectName}项目的${env.repoName}这些标签:",
parameters: [extendedChoice(defaultValue: "${env.result}",
multiSelectDelimiter: ',',
name: 'taga',
quoteValue: false,
saveJSONParameterToFile: false,
type: 'PT_CHECKBOX',
value: "${env.result}",
visibleItemCount: 20)]
println("${result}")
// println("Delete ${taga}, doing.......")
// tags = "${taga}" - '[' - ']'
for(t in result.split(',')){
println("Delete >>>>" + t.trim())
DeleteArtifactTag(env.projectName,env.repoName, t.trim())
}
}
}
}
}
}
// 删除镜像tag
def DeleteArtifactTag(projectName,repoName, tagName){
harborAPI = "http://172.29.9.103:8088/api/v2.0/projects/${projectName}/repositories/${repoName}"
apiURL = "artifacts/${tagName}/tags/${tagName}"
sh """ curl -X DELETE "${harborAPI}/${apiURL}" -H "accept: application/json" -u admin:Harbor12345 """
}
// 获取镜像的所有标签
// acmp-nginx-service
def GetArtifactTag(projectName,repoName ){
harborAPI = "http://172.29.9.103:8088/api/v2.0/projects/${projectName}/repositories/${repoName}"
apiURL = "artifacts?page=1&page_size=10"
response = sh returnStdout: true, script: """curl -X GET "${harborAPI}/${apiURL}" -H "accept: application/json" -u admin:Harbor12345 """
response = readJSON text: """${response - "\n"}"""
tags = []
for (t in response[0].tags){
tags << t.name
}
return tags
}